/*
 * sc_log.h
 *
 *  Created on: Sep 2, 2010
 *      Author: sdaniele
 */

#ifndef SC_LOG_H_
#define SC_LOG_H_

#include "sysc/kernel/dbgprint_config.hpp"

#include <boost/function.hpp>
#include <boost/unordered_map.hpp>
#include <vector>

#include "sysc/kernel/sc_time.h"

namespace sc_core {

class sc_event;
class sc_event_or_list;
class sc_event_and_list;
class sc_prim_channel;
class sc_process_b;

struct sc_event_log {
        bool            m_has_delta_timed;
        bool            m_has_immediate;
        sc_time         m_time;
        bool   			m_has_subscriber;

        sc_event_log()
                : m_has_delta_timed(false)
                , m_has_immediate(false)
                , m_has_subscriber(false)
        {}

        void dump(){
        	with_tag<opt_log>::println("@@ dump of sc_event_log=",this,"\n\thas_delta_timed=",m_has_delta_timed,"\n\thas_immediate="
        			,m_has_immediate,"\n\ttime=",m_time,"\n\tsubscriber=",m_has_subscriber);
        }

        void reset(){
			m_has_delta_timed = false;
			m_has_immediate = false;
			m_has_subscriber = false;
        }
};

struct sc_log {

	typedef boost::unordered_map<sc_event*,sc_event_log> 	map_t;
	typedef boost::function<void()> 						action_t;
	typedef std::vector<action_t> 							log_t;

	log_t           m_log;
	map_t           m_event_logs;
	sc_process_b*   m_curr_proc;

	sc_log(sc_process_b* p) : m_curr_proc(p) {}

	void cancel(sc_event*);
	void notify(sc_event*);
	void notify(sc_event*, const sc_time&);
    void notify_delayed(sc_event*);
    void notify_delayed(sc_event*, const sc_time&);
	void notify_internal(sc_event*, const sc_time&);
	void notify_next_delta(sc_event*);

	void request_update(sc_prim_channel*);

	void next_trigger();
	void next_trigger(const sc_event&);
	void next_trigger(sc_event_or_list&);
	void next_trigger(sc_event_and_list&);
	void next_trigger(const sc_time&);
	void next_trigger(const sc_time&, const sc_event&);
	void next_trigger(const sc_time&, sc_event_or_list&);
	void next_trigger(const sc_time&, sc_event_and_list&);

	void execute_and_reset();

private:
	void execute_event_logs();
};


}

#endif /* SC_LOG_H_ */
